// var l = { x: 10 }
// var g = l
// l.y = l = { x: 200 }

// console.log(l.y)
// console.log(g)

// 基本值类型（原始值）
/*代码运行之前，会有个变量提升操作
 *对于var来说，声明是发生在变量提升阶段
 *代码执行的时候是定义
 *
 *
 *定义时，基本数据类型是直接存放在栈区的
 *
 *首先在当前执行上下文中查找，找不到就向上找
 *如果在EC（G）全局执行上下文页找不到，就会去GO全局对象去查找
 *GO在浏览器加载界面时就创建了，既然是一个对象，肯定会有一个内存地址，16进制
 *GO当中的内容默认情况下和EC（G）是没有关系
 *所以为了方便EC（G）可以直接用GO里面的内容，js在VO（G）当中就准备了一个变量，叫window
 *如果GO当中也没有找到，会报错，当前变量未定义(ReferenceError: aaa is not defined)
 */
var l = 100;
var g = l;
g = 101;
console.log(l);

// 堆栈中的引用类型
/**
 * 引用类型在js中会单独开辟一个空间进行存储（堆区）
 * 堆区本质上也是一个内存，所以也会有一个16进制的地址
 * 在栈区当中存放的是这个内存的16进制地址
 * 如果堆区的值也是一个引用类型，那么需要再次开辟一个空间进行存储
 */
var l = { x: 17 };
var g = l;
g["y"] = 120;
console.log(l.y);


// 堆栈中的函数类型
/**
 * 1.对于函数我们考虑2个操作，一个是函数的声明定义，一个是函数的执行
 * 2.对于函数来说，变量提升阶段，既声明又定义
 * 3.函数的创建和变量的创建类似，我们可以将函数名看做是一个变量名，只不过在提升阶段会直接定义
 * 4.函数也是一个对象，因此也同样在堆中存储，有个16进制的地址，将内存地址存放在栈区中
 * 5.对于函数来说，声明和定义都是发生在提升阶段，因此在代码运行时看到了function foo(){}这种代码时一般是不做处理的
 * 6.函数在创建时就创建了作用域，也就是当前所在上下文
 * 7.在创建函数的时候，他的内存当中存放的是字符串形式的函数体
 * 8.函数执行的目的是为了将他内存当中存储的字符串形式的代码运行起来，此时为了保证当前代码与其他上下文当中的代码时互相隔离的，所以每个函数执行时都会生成一个全新的执行上下文
 * 9.如果函数执行过程中，有形参赋值操作，那么就会在AO(FOO)当中新增属性
 * 
 * 
 * 
 * 函数执行步骤：
 * 1.确定作用域链
 * 2.确定函数中的this
 * 3.初始化arguments
 * 4.形参赋值
 * 5.变量提升
 * 6.函数代码执行
 */